
package com.jims.master.modules.doctor.service;

import com.google.common.collect.Lists;
import com.jims.master.common.config.Global;
import com.jims.master.common.service.CrudService;
import com.jims.master.common.utils.StringUtils;
import com.jims.master.modules.doctor.dao.*;
import com.jims.master.modules.doctor.entity.*;
import com.jims.master.modules.doctor.vo.PrescDrugVo;
import com.jims.master.modules.drug.dao.DrugDictDao;
import com.jims.master.modules.drug.dao.DrugInfoDao;
import com.jims.master.modules.drug.dao.DrugPriceDao;
import com.jims.master.modules.drug.entity.DrugDict;
import com.jims.master.modules.drug.entity.DrugInfo;
import com.jims.master.modules.oper.dao.ClinicItemDictDao;
import com.jims.master.modules.oper.dao.PriceListDao;
import com.jims.master.modules.oper.entity.ClinicItemDict;
import com.jims.master.modules.oper.entity.PriceList;
import com.jims.master.modules.sys.dao.PerformFreqDictDao;
import com.jims.master.modules.sys.dao.SysOrgDictDao;
import com.jims.master.modules.sys.entity.PerformFreqDict;
import com.jims.master.modules.sys.entity.SysOrgDict;
import com.jims.master.modules.sys.entity.User;
import com.jims.master.modules.sys.utils.UserUtils;
import com.jims.master.modules.template.service.TreatProjectItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


/**
 * 门诊处方明细Service
 *
 * @author CTQ
 * @version 2017-03-13
 */
@Service
@Transactional(readOnly = true)
public class PrescriptionItemService extends CrudService<PrescriptionItemDao, PrescriptionItem> {
    @Autowired
    private PrescriptionApplyDao applyDao;
    @Autowired
    private PrescriptionItemDao prescriptionItemDao;
    @Autowired
    private ClinicOrdersDao clinicOrdersDao;
    @Autowired
    private ClinicOrdersCostDao clinicOrdersCostDao;
    @Autowired
    private PriceListDao priceListDao;
    @Autowired
    private PerformFreqDictDao performFreqDictDao;
    @Autowired
    private DrugInfoDao drugInfoDao;
    @Autowired
    private DrugDictDao drugDictDao;
    @Autowired
    private OutpTreatPrescDao outpTreatPrescDao;
    @Autowired
    private ClinicItemDictDao clinicItemDictDao;
    @Autowired
    private OutpTreatRecService outpTreatRecService;
    @Autowired
    private SysOrgDictDao sysOrgDictDao;
    @Autowired
    private TreatProjectItemService treatProjectItemService;
    @Autowired
    private ClinicMasterService clinicMasterService;
    @Autowired
    private DrugPriceDao drugPriceDao;

    /**
     * 根据参数查询
     *
     * @param q
     * @param limit
     * @param drugClass
     * @return
     * @author CTQ
     */
    public List<PrescDrugVo> findListByParam(String q, String limit, String drugClass, String storageId, String orgId) {
        return dao.findListByParam(q, limit, drugClass, storageId, orgId);
    }

    /**
     * 根据处方主表id查询处方明细
     *
     * @param prescriptionItem
     * @return
     * @author CTQ
     */
    public List<PrescriptionItem> findListByApplyId(PrescriptionItem prescriptionItem) {
        return dao.findListByApplyId(prescriptionItem);
    }

    /**
     * 根据处方ID删除明细
     *
     * @param applyId
     * @return
     */
    @Transactional(readOnly = false)
    public int delByApplyId(String applyId) {
        return dao.delByApplyId(applyId);
    }

    @Transactional(readOnly = false)


    public int saveWest(PrescriptionItem prescriptionItem) {
        int num = 0;

        PrescriptionItem parent = new PrescriptionItem();
        if (prescriptionItem.getParent() != null && StringUtils.isNotBlank(prescriptionItem.getParent().getId())) {
            parent = prescriptionItemDao.get(prescriptionItem.getParent().getId());
            if (parent != null) {
                prescriptionItem.setChannel(parent.getChannel());
                prescriptionItem.setFrequency(parent.getFrequency());
            }
        }

        prescriptionItem.setSumPrice(prescriptionItem.getPrice()*prescriptionItem.getNum());
        if ("".equals(prescriptionItem.getTempalteId()) || prescriptionItem.getTempalteId() == null) {
            prescriptionItem.preInsert();
        }
        prescriptionItem.updateOrgId();
        num = dao.insert(prescriptionItem);

        return num;
    }

    /**
     * 保存中药信息
     *
     * @param prescriptionItem
     * @return
     */
    @Transactional(readOnly = false)
    public int saveChina(PrescriptionItem prescriptionItem, String isDecoction,String clinicId,String visitId) {
        int num = 0;
        List<PrescriptionItem> itemList = Lists.newArrayList();
        List<ClinicOrdersCost> costList = Lists.newArrayList();

        if (StringUtils.isNotBlank(prescriptionItem.getApplyId())) {

            PrescriptionApply apply = applyDao.get(prescriptionItem.getApplyId());
            if (apply != null) {
                /**删除中药处方明细**/
                prescriptionItemDao.delByApplyId(apply.getId());
                /**2.删除orders与orders_cost*/
                if (StringUtils.isNotBlank(apply.getOrdersId())) {
                    clinicOrdersCostDao.delByOrderId(apply.getOrdersId());
                    clinicOrdersDao.delete(new ClinicOrders(apply.getOrdersId()));
                }
                ClinicOrders orders = handleOrders(apply);

                if(prescriptionItem.getClinicId() != null && !"".equals(prescriptionItem.getClinicId())){
                    ClinicMaster clinicMaster=clinicMasterService.get(prescriptionItem.getClinicId());
                    User user= UserUtils.getUser();
                    String doctorId=clinicMaster.getDoctorId();
                    clinicMaster.setClinicType("1");
                    if(doctorId == null){
                        clinicMaster.setDoctorId(user.getId());
                    }
                    else{
                        clinicMaster.setDoctorId(clinicMaster.getDoctorId());
                    }
                    clinicMaster.setId(clinicId);
                    //修改clinic_master挂号状态
                    int m = clinicMasterService.updateClinicType(clinicMaster);
                    orders.setApplyDept(clinicMaster.getDeptId());
                    orders.updateOrgId();
                    orders.preInsert();
                    clinicOrdersDao.insert(orders);
                    /**更新申请表状态**/
                    apply.setOrdersId(orders.getId());

                    /**处理药品费用明细**/
                    if (prescriptionItem.getItemList() != null && prescriptionItem.getItemList().size() > 0) {
                        for (PrescriptionItem item : prescriptionItem.getItemList()) {
                            if (item != null) {
                                item.setApplyId(prescriptionItem.getApplyId());
                                item.setFrequency(prescriptionItem.getFrequency());
                                item.setRepetition(prescriptionItem.getRepetition());
                                item.setChannel(prescriptionItem.getChannel());
                                item.setAbidance(1);
                                itemList.add(item);
                                ClinicOrdersCost clinicOrdersCost = new ClinicOrdersCost();
                                costList.add(handleCost(item, clinicOrdersCost));
                                /**处理药品途径费用信息**/
                                if (item.getParent() == null) {

                                    handleAdministration(item, apply);
                                }
                            }
                        }
                        if (!"1".equals(isDecoction)) {
                            SysOrgDict orgDict = sysOrgDictDao.get(isDecoction);
                            String orgId = UserUtils.getOrgId();
                            if ("代煎".equals(orgDict.getLabel())) {
                                SysOrgDict orgDictP = sysOrgDictDao.getSysOrgById("CLINIC_DICT", "代煎");
                                List<ClinicItemDict> listp = clinicItemDictDao.findClinicItemByDictId(isDecoction, orgId);
                                for (int i = 0; i < listp.size(); i++) {
                                    ClinicItemDict dict = listp.get(i);
                                    OutpTreatRec outpTreatRec = new OutpTreatRec();
                                    outpTreatRec.setClinicId(apply.getClinicId());
                                    outpTreatRec.setPatientId(apply.getPatientId());
                                    outpTreatRec.setNum(String.valueOf(1));
                                    outpTreatRec.setClinicItemId(dict.getId());
                                    outpTreatRec.setImplementDept(dict.getExpand1());
                                    outpTreatRec.setInoroutFlag(apply.getInoroutFlag());
                                    outpTreatRec.setConfirmFlag(apply.getConfirmFlag());
                                    outpTreatRec.setChargeFlag(apply.getChargeFlag());
                                    outpTreatRec.setOrdersId(apply.getOrdersId());
                                    String treatId = outpTreatRecService.saveOutpTreatRec(outpTreatRec);
//								OutpTreatPresc outpTreatPresc = handleTreat(prescriptionItem,new OutpTreatPresc());
//								outpTreatPresc.preInsert();
//								outpTreatPresc.updateOrgId();
//								outpTreatPresc.setTreatId(treatId);
//								outpTreatPrescDao.insert(outpTreatPresc);
                                }
                            }

                        }
                    }
                } else {
                    for (PrescriptionItem item : prescriptionItem.getItemList()) {
                        if (item != null) {
                            item.setApplyId(prescriptionItem.getApplyId());
                            item.setFrequency(prescriptionItem.getFrequency());
                            item.setRepetition(prescriptionItem.getRepetition());
                            item.setChannel(prescriptionItem.getChannel());
                            item.setAbidance(1);
                            itemList.add(item);
                        }
                    }
                }
                apply.setPrescStatus(Global.YES);
                apply.preUpdate();

                applyDao.update(apply);
                saveOrdersCosts(orders, costList);
                num = saveItemList(itemList);
            }
        }
        return num;
    }



    /**
     * 处理药品途径
     *
     * @param prescriptionItem
     * @author CTQ
     */
    @Transactional(readOnly = false)
    public void handleAdministration(PrescriptionItem prescriptionItem, PrescriptionApply prescriptionApply) {
        SysOrgDict orgDict = sysOrgDictDao.get(prescriptionItem.getChannel());
        String orgId = UserUtils.getOrgId();
        List<ClinicItemDict> list = clinicItemDictDao.findClinicItemByDictId(prescriptionItem.getChannel(), orgId);
        for (int i = 0; i < list.size(); i++) {
            ClinicItemDict dict = list.get(i);
            OutpTreatRec outpTreatRec = new OutpTreatRec();
            outpTreatRec.setClinicId(prescriptionApply.getClinicId());
            outpTreatRec.setPatientId(prescriptionApply.getPatientId());
            outpTreatRec.setNum(String.valueOf(1));
            outpTreatRec.setClinicItemId(dict.getId());
            outpTreatRec.setImplementDept(dict.getExpand1());
            String treatId = outpTreatRecService.saveOutpTreatRec(outpTreatRec);
            if ("皮试".equals(orgDict.getLabel()) || prescriptionItem.getIsSkin().equals(Global.YES)) {
                OutpTreatPresc outpTreatPresc = handleTreat(prescriptionItem, new OutpTreatPresc());
                outpTreatPresc.preInsert();
                outpTreatPresc.updateOrgId();
                outpTreatPresc.setTreatId(treatId);
                outpTreatPrescDao.insert(outpTreatPresc);
            }
        }
        if(orgDict != null){
            if ("皮试".equals(orgDict.getLabel()) && (prescriptionItem.getIsSkin() != null && prescriptionItem.getIsSkin().equals(Global.YES))) {
                SysOrgDict orgDictP = sysOrgDictDao.getSysOrgById("ADMINISTRATION_DICT", "皮试");
                List<ClinicItemDict> listp = clinicItemDictDao.findClinicItemByDictId(prescriptionItem.getChannel(), orgId);
                for (int i = 0; i < listp.size(); i++) {
                    ClinicItemDict dict = listp.get(i);
                    OutpTreatRec outpTreatRec = new OutpTreatRec();
                    outpTreatRec.setClinicId(prescriptionApply.getClinicId());
                    outpTreatRec.setPatientId(prescriptionApply.getPatientId());
                    outpTreatRec.setNum(String.valueOf(1));
                    outpTreatRec.setClinicItemId(dict.getId());
                    outpTreatRec.setImplementDept(dict.getExpand1());
                    outpTreatRec.setInoroutFlag(prescriptionApply.getInoroutFlag());
                    outpTreatRec.setConfirmFlag(prescriptionApply.getConfirmFlag());
                    outpTreatRec.setChargeFlag(prescriptionApply.getChargeFlag());
                    outpTreatRec.setOrdersId(prescriptionApply.getOrdersId());
                    outpTreatRecService.save(outpTreatRec);
                }
            }
        }
    }

    /**
     * 处理皮试药品治疗数据
     *
     * @param prescriptionItem
     * @param outpTreatPresc
     * @return
     * @author CTQ
     */
    private OutpTreatPresc handleTreat(PrescriptionItem prescriptionItem, OutpTreatPresc outpTreatPresc) {
        outpTreatPresc.setUnit(prescriptionItem.getUnit());
        outpTreatPresc.setDrugCode(prescriptionItem.getDrugCode());
        outpTreatPresc.setChannel(prescriptionItem.getChannel());
        outpTreatPresc.setDrugName(prescriptionItem.getDrugName());
        outpTreatPresc.setPackageSpec(prescriptionItem.getPackageSpec());
        outpTreatPresc.setFirmId(prescriptionItem.getFirmId());
        outpTreatPresc.setFirmName(prescriptionItem.getFirmName());
        outpTreatPresc.setFrequency(prescriptionItem.getFrequency());
        outpTreatPresc.setIsSkin(prescriptionItem.getIsSkin());
        outpTreatPresc.setNum(prescriptionItem.getNum());
        outpTreatPresc.setPackageUnit(prescriptionItem.getPackageUnit());
        outpTreatPresc.setTreatId(prescriptionItem.getApplyId());
        outpTreatPresc.setPrescId(prescriptionItem.getId());
        outpTreatPresc.setSumPrice(prescriptionItem.getSumPrice());
        outpTreatPresc.setPrice(prescriptionItem.getPrice());
        outpTreatPresc.setSingleDosage(prescriptionItem.getSingleDosage());
        outpTreatPresc.setSingleUnit(prescriptionItem.getSingleUnit());
        outpTreatPresc.setSkinResult(prescriptionItem.getSkinResult());
        outpTreatPresc.setSpec(prescriptionItem.getSpec());
        return outpTreatPresc;
    }

    /**
     * 处理医嘱信息
     *
     * @param prescriptionApply
     * @return
     * @author CTQ
     */
    private ClinicOrders handleOrders(PrescriptionApply prescriptionApply) {
        ClinicOrders orders = new ClinicOrders();
        orders.setApplyId(prescriptionApply.getId());
        orders.setApplyNo(prescriptionApply.getApplyOn());
        orders.setChargeFlag("0");//是否收费
        orders.setClinicId(prescriptionApply.getClinicId());
        orders.setImplementDept(prescriptionApply.getImplementDept());
        orders.setItemClass(prescriptionApply.getItemClass());
        orders.setPatientId(prescriptionApply.getPatientId());
        orders.setIsApply(Global.YES);//是否是申请单
        return orders;
    }

    /**
     * 处理医嘱明细
     *
     * @param prescriptionItem
     * @param clinicOrdersCost
     * @return
     * @author CTQ
     */
    private ClinicOrdersCost handleCost(PrescriptionItem prescriptionItem, ClinicOrdersCost clinicOrdersCost) {
        if (StringUtils.isNotBlank(prescriptionItem.getDrugCode())) {
            PriceList priceList = priceListDao.get(prescriptionItem.getPriceId());
            clinicOrdersCost.setPriceId(priceList.getId());
            clinicOrdersCost.setSubjCode(priceList.getSubjCode());//会计科目
            clinicOrdersCost.setCoefficient(Double.valueOf(1));//收费系数
            clinicOrdersCost.setClassOnReckoning(priceList.getClassOnReckoning());//核算项目科目
            clinicOrdersCost.setItemClass(priceList.getItemClass());
            clinicOrdersCost.setItemName(prescriptionItem.getDrugName());
            clinicOrdersCost.setItemCode(prescriptionItem.getDrugCode());
            clinicOrdersCost.setNum(prescriptionItem.getNum());
            clinicOrdersCost.setSpec(prescriptionItem.getSpec());
            clinicOrdersCost.setUnit(prescriptionItem.getUnit());
        }

        return clinicOrdersCost;
    }

    /**
     * 保存处方明细
     *
     * @param list
     */
    @Transactional(readOnly = false)
    private int saveItemList(List<PrescriptionItem> list) {
        int num = 0;
        if (list != null && list.size() > 0) {
            for (PrescriptionItem item : list) {
                if (StringUtils.isNotBlank(item.getDrugCode())) {
                    item.setSumPrice(item.getNum() * item.getPrice());
                    item.preInsert();
                    item.updateOrgId();
                    num = dao.insert(item);
                }
            }
        }
        return num;
    }

    /**
     * 保存医嘱明细数据
     *
     * @param orders
     * @return
     * @author CTQ
     */
    @Transactional(readOnly = false)
    private void saveOrdersCosts(ClinicOrders orders, List<ClinicOrdersCost> list) {
        if (list != null && list.size() > 0) {
            for (ClinicOrdersCost cost : list) {
                if (StringUtils.isNotBlank(cost.getItemClass())) {
                    cost.setPatientId(orders.getPatientId());
                    cost.setClinicId(orders.getClinicId());
                    cost.setOrdersId(orders.getId());
                    cost.updateOrgId();
                    cost.preInsert();
                    clinicOrdersCostDao.insert(cost);
                }
            }
        }
    }

    /**
     * 根据处方主表id查询处方明细
     *
     * @param prescriptionItem
     * @return
     * @author ZhuQ
     */
    public List<PrescriptionItem> findByApplyId(PrescriptionItem prescriptionItem) {
        return dao.findByApplyId(prescriptionItem);
    }

    public List<PrescriptionItem> getPreItem(PrescriptionItem prescriptionItem) {
        List<PrescriptionItem> list = dao.getPreItem(prescriptionItem);
        return list;
    }


    public List<PrescriptionItem> selectHistory(String applyId) {
        return dao.selectHistory(applyId);
    }

    @Transactional(readOnly = false)
    public String saveTreatTemplate(String id, String fTreatId, String clinicId, String patientId, String prescApplyId, List<PrescriptionItem> prescriptionItemList) {
        int num = 0;
        String fId = "";
        for (int i = 1; i < prescriptionItemList.size(); i++) {
            PrescriptionItem prescriptionItem = prescriptionItemList.get(i);
            prescriptionItem.setApplyId(prescApplyId);
            prescriptionItem.setRepetition(1);
            prescriptionItem.setSumPrice(prescriptionItem.getNum() * prescriptionItem.getPrice());
            if (StringUtils.isBlank(prescriptionItem.getParent().getId())) {
                prescriptionItem.preInsert();
                fId = prescriptionItem.getId();
                fTreatId = prescriptionItem.getTempalteId();
            } else {
                if (prescriptionItem.getParent().getId().equals(fTreatId)) {
                    prescriptionItem.preInsert();
                    prescriptionItem.getParent().setId(fId);
                } else {
                    prescriptionItem.preInsert();
//					fFlag=i;
//					fTreatId=prescriptionItem.getTempalteId();
//					fId=prescriptionItem.getId();
                }
            }
            num += saveWest(prescriptionItem);
        }
        return num + "";
    }

    public int calculatedquantity(PrescriptionItem prescriptionItem) {
        Double drugNum = 0.00; // 药品数量
//      if (prescriptionItem.getAbidance() != null && !"".equals(prescriptionItem.getNum())) {
        if (StringUtils.isNotBlank(prescriptionItem.getFrequency())) {
            PerformFreqDict performFreqDict = performFreqDictDao.get(prescriptionItem.getFrequency());
            DrugDict dict = new DrugDict();
            if (performFreqDict != null) {
                Double dosage = prescriptionItem.getSingleDosage();//获取单次用量
                Integer repetition = prescriptionItem.getRepetition();//获取计数
                Double freqCounter = Double.parseDouble(performFreqDict.getFreqCounter());//频率次数
                Double freqInterval = Double.parseDouble(performFreqDict.getFreqInterval());//频率间隔
                String freUnit = performFreqDict.getFreqIntervalUnit();//间隔单位
                int abidance = prescriptionItem.getAbidance()==null?1:prescriptionItem.getAbidance(); // 天数

                if (freqInterval.equals(Double.valueOf(0))) {
                    freqInterval = 1.00;
                }
                if (prescriptionItem.getPackageSpec().contains("*")) {//大包装
                    /**查询药品信息**/
                    DrugInfo drugInfo = new DrugInfo();

//                    dict.setDrugCode(prescriptionItem.getDrugCode());
//                    drugInfo.setDrugDict(dict);
//                    drugInfo.setPackageSpec(prescriptionItem.getPackageSpec());
//                    drugInfo.setPackageUnit(prescriptionItem.getPackageUnit());
//                    drugInfo.setMinSpec(prescriptionItem.getSpec());
//                    drugInfo.setMinUnits(prescriptionItem.getUnit());
//                    drugInfo.setDrugSupplierCata(new DrugSupplierCata(prescriptionItem.getFirmId()));
////                    DrugPrice drugPrice = drugPriceDao.get(prescriptionItem.getPriceId());
                    DrugInfo info = drugInfoDao.get(drugPriceDao.get(prescriptionItem.getPriceId()).getDrugInfo());
//                    DrugInfo info = drugInfoDao.findDrugInfo(drugInfo);
                    //数量计算 （用药天数*频次*单次用量）/包装规格

                    if (performFreqDict != null) {
                        if (info != null) {
                            if ("周".equals(freUnit)) {
                                drugNum = (abidance * dosage * freqInterval * freqCounter / 7) / (info.getPackageNum() * Double.valueOf(info.getDrugDict().getDosePerUnit()));
                            } else if ("小时".equals(freUnit)) {
                                drugNum = (abidance * dosage * freqInterval * freqCounter * 24) / (info.getPackageNum() * Double.valueOf(info.getDrugDict().getDosePerUnit()));
                            } else {
                                drugNum = (abidance * dosage * freqInterval * freqCounter) / (info.getPackageNum() * Double.valueOf(info.getDrugDict().getDosePerUnit()));
                            }
                        }
                    }
                } else {//小包装
                    dict.setDrugCode(prescriptionItem.getDrugCode());
                    dict.setDrugSpec(prescriptionItem.getPackageSpec());
                    dict.setUnit(prescriptionItem.getPackageUnit());
                    List<DrugDict> list = drugDictDao.findByDrugCode(dict);
                    if (list != null && list.size() > 0) {
                        DrugDict drugDict = list.get(0);
                        if ("周".equals(freUnit)) {
                            drugNum = (abidance * dosage * freqInterval * freqCounter / 7) / (Double.valueOf(drugDict.getDosePerUnit()));
                        } else if ("小时".equals(freUnit)) {
                            drugNum = (abidance * dosage * freqInterval * freqCounter * 24) / (Double.valueOf(drugDict.getDosePerUnit()));
                        } else {
                            drugNum = (abidance * dosage * freqInterval * freqCounter) / (Double.valueOf(drugDict.getDosePerUnit()));
                        }
                    }
                }
            }
        }

    return (int) Math.ceil(drugNum);
    }
}
